"""
【唯一】
Definition: 单例模式（Singleton Pattern）是一种创建型设计模式，它保证一个类仅有一个实例，并提供访问该实例的全局访问点。

优：唯一性、全局性
缺：降低代码灵活性与可拓展

Code: 定义了一个名为 Singleton 的类，并使用了 Python 的双下划线命名方式将其实现为私有化类。在 __new__() 方法中，
      使用了一个静态变量 __instance 来保存实例对象，如果该变量为空，则创建一个新的实例并返回；否则直接返回已存在的实例。

优缺：
    懒汉式可以避免无用的资源消耗，但也会带来多线程安全问题；
    饿汉式可以确保实例的唯一性和线程安全性，但可能会引起不必要的开销；
    双重检查锁定可以解决懒汉式和饿汉式的缺点，但也存在一些问题难以排除现象。
"""


class Singleton:
    __instance = None

    def __new__(cls):
        if cls.__instance is None:
            cls.__instance = (
                object.__new__(cls))
        return cls.__instance


s1 = Singleton()
s2 = Singleton()
print(s1 is s2)
# 输出：True =》 说明唯一性


"""
懒汉式单例模式

Code: 使用了 Python 的双下划线命名方式将其实现为私有化类。然后，通过静态方法 get_instance() 来获取该类的实例。
      如果实例不存在，则创建一个新的实例；否则直接返回已存在的实例
"""
class Singleton1:
    __instance = None

    @staticmethod
    def get_instance():
        if Singleton1.__instance is None:
            Singleton1()
        return Singleton1.__instance

    def __init__(self):
        if Singleton1.__instance is not None:
            raise Exception(
                "This class is a singleton!")
        else:
            Singleton1.__instance = self


"""
饿汉式单例模式
Code: 与懒汉式不同的是，在定义类时就已经创建了该类的实例并赋值给静态变量 __instance。
      然后，同样通过静态方法 get_instance() 来获取该类的实例，并直接返回已存在的实例即可。
"""
class Singleton2:
    __instance = Singleton2()

    @staticmethod
    def get_instance():
        return Singleton2.__instance


"""
双重检查锁定单例模式
Code: 与懒汉式不同的是，我们使用了一个静态变量 __lock 来控制多线程环境下对实例的访问。
      然后，在获取实例时，首先检查实例是否存在，如果不存在则进入加锁状态再次检查，若再不存在则在创建实例时
"""
import threading


class Singleton:
    __instance = None
    __lock = threading.Lock()

    @staticmethod
    def get_instance():
        if Singleton.__instance is None:
            with Singleton.__lock:
                if Singleton.__instance is None:
                    Singleton()
        return Singleton.__instance

    def __init__(self):
        if Singleton.__instance is not None:
            raise Exception(
                "This class is a singleton!")
        else:
            Singleton.__instance = self
